package com.lumberer.pay2021.wx.verify;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.servlet.http.HttpServletRequest;

import org.springframework.util.Base64Utils;

import com.alibaba.fastjson.JSON;
import com.lumberer.pay2021.wx.init.config.MerchantConfig;
import com.lumberer.pay2021.wx.init.config.RequestURL;
import com.lumberer.pay2021.wx.init.loading.CertificateLoad;
import com.lumberer.pay2021.wx.jsapi.payment.entity.PayData;
import com.lumberer.pay2021.wx.jsapi.payment.entity.notify.Notify;

import okhttp3.HttpUrl;
/**
 * 微信支付验证回调
 * @author lumberer
 * @date 2021年9月22日
 */
public class VerifyNotify {
	/**
	 * 发送HTTP请求明文拼装
	 * @param method+
	 * @param payData
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String notifyMessage(String method, PayData payData) throws UnsupportedEncodingException {
		HttpUrl uri = HttpUrl.parse(RequestURL.JSAPI);
		String canonicalUrl = uri.encodedPath();
		if (uri.encodedQuery() != null) {
			canonicalUrl += "?" + uri.encodedQuery();
		}
		String signStr = method+"\n" + canonicalUrl + "\n" + String.valueOf(payData.getTimeStamp()) + "\n"
				+ payData.getNonceStr() + "\n" + JSON.toJSONString(payData) + "\n";
		return signStr;
	}
	 /**
     * 验证微信回调签名
     * @param request
     * @param body
     * @return
     */
    public static boolean verifiedSign(HttpServletRequest request,Notify notify) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        //微信返回的证书序列号
    	String body=JSON.toJSONString(notify);
        String serialNo = request.getHeader("Wechatpay-Serial");
        //微信返回的随机字符串
        String nonceStr = request.getHeader("Wechatpay-Nonce");
        //微信返回的时间戳
        String timestamp = request.getHeader("Wechatpay-Timestamp");
        //微信返回的签名
        String wechatSign = request.getHeader("Wechatpay-Signature");
        //组装签名字符串
        String signStr = Stream.of(timestamp, nonceStr, body)
                .collect(Collectors.joining("\n", "", "\n"));
        //当证书容器为空 或者 响应提供的证书序列号不在容器中时  就应该刷新了
        if (MerchantConfig.certificateMap.isEmpty() || !MerchantConfig.certificateMap.containsKey(serialNo)) {
        	MerchantConfig.certificateMap=CertificateLoad.refreshCertificate();
        }
        //根据序列号获取平台证书
        X509Certificate certificate = MerchantConfig.certificateMap.get(serialNo);
        //获取失败 验证失败
        if (certificate == null){
            return false;
        }
        //SHA256withRSA签名
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(certificate);
        signature.update(signStr.getBytes());
        //返回验签结果
        return signature.verify(Base64Utils.decodeFromString(wechatSign));
    }
}
